package yl.hs.bmipfull.controllers.production;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import yl.hs.bmipfull.controllers.ControllerBase;
import yl.hs.bmipfull.pojo.production.BrickShipOrderModel;
import yl.hs.bmipfull.service.production.IBrickShipService;
import yl.hs.bmipfull.service.system.ISearchViewService;
import yl.hs.bmipfull.utils.ExcelMapUtil;
import yl.hs.bmipfull.utils.Tl;
import yl.hs.bmipfull.viewmodels.PageQuery;
import yl.hs.bmipfull.viewmodels.SubmitModel;
import yl.hs.bmipfull.viewmodels.WebResult;
import yl.hs.bmipfull.viewmodels.system.ExcelMap;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/*
 * BrickShipOrderController
 * @category
 * @author 谢景广
 * @date 2022-12-13
 */
@Api(value = "成品砖发货单Web接口", tags = "生产管理——成品砖发货单操作")
@Slf4j
@RestController
@RequestMapping("/api/brick/ship")
public class BrickShipOrderController extends ControllerBase {

    @ApiOperation(value = "查询产品发货单", notes = "查询产品发货单")
    @RequestMapping(value = "order", method = RequestMethod.POST)
    public WebResult queryList(@ApiParam(value = "查询条件") @RequestBody PageQuery pageQuery) {
        try {
            return success("查询成功", shipService.queryList(pageQuery));
        } catch (Exception e) {
            return error(e);
        }
    }

    @ApiOperation(value = "查询产品发货单", notes = "分页查询产品发货单")
    @RequestMapping(value = "order/{rowNum}/{page}", method = RequestMethod.POST)
    public WebResult queryOrderPage(@RequestBody PageQuery query,
                                    @ApiParam(value = "页码") @PathVariable int page,
                                    @ApiParam(value = "每页条数") @PathVariable int rowNum) {
        try {
            var data = shipService.queryList(query);
            var result = shipService.queryOrderPage(query, rowNum, page);
            val map = Tl.toMap(result);
            var sumQuantity = data.stream().mapToDouble(s -> Double.parseDouble((s.getQuantity() == null ? 0 : s.getQuantity()).toString())).sum();
            var sumVolume = data.stream().mapToDouble(s -> Double.parseDouble((s.getVolume() == null ? 0 : s.getVolume()).toString())).sum();
            map.put("sumQuantity", sumQuantity);
            map.put("sumVolume", sumVolume);
            svSVC.updateUserMenuView(query);
            return success("ok", map);
        } catch (Exception ee) {
            return error(ee);
        }
    }
    @ApiOperation(value = "查询产品发货单", notes = "分页查询产品发货单")
    @RequestMapping(value = "ordership", method = RequestMethod.POST)
    public WebResult queryOrderShip(@RequestBody PageQuery query) {
        try {
            Map<String,Object> map;
            List<Object> datas = new ArrayList<>();
            var data = shipService.queryList(query);
            var result =  data.stream().collect(Collectors.groupingBy(BrickShipOrderModel::getProductSN));
            var list = result.keySet();
            for (String s : list) {
                map = new HashMap<>();
                var ss = result.get(s);
                map.put("productCate",ss.get(0).getProductCate());
                map.put("productName",ss.get(0).getProductName());
                map.put("productSpec",ss.get(0).getProductSpec());
                map.put("quantity",ss.stream().map(BrickShipOrderModel::getQuantity).reduce(BigDecimal::add));
                datas.add(map);
            }
            return success("查询成功",datas);
        } catch (Exception ee) {
            return error(ee);
        }
    }
    @ApiOperation(value = "查询产品发货单明细", notes = "分页查询产品发货单明细")
    @RequestMapping(value = "model/{rowNum}/{page}", method = RequestMethod.POST)
    public WebResult queryModelPage(@RequestBody PageQuery query,
                                    @ApiParam(value = "页码") @PathVariable int page,
                                    @ApiParam(value = "每页条数") @PathVariable int rowNum) {
        try {
            var data = shipService.queryList(query);
            var result = shipService.queryModelPage(query, rowNum, page);
            val map = Tl.toMap(result);
            var sumQuantity = data.stream().mapToDouble(s -> Double.parseDouble((s.getQuantity() == null ? 0 : s.getQuantity()).toString())).sum();
            var sumVolume = data.stream().mapToDouble(s -> Double.parseDouble((s.getVolume() == null ? 0 : s.getVolume()).toString())).sum();
            var sumShipmentReviewVolume = data.stream().mapToDouble(s -> Double.parseDouble((s.getShipmentReviewVolume() == null ? 0 : s.getShipmentReviewVolume()).toString())).sum();
            var sumShipmentReviewQuantity = data.stream().mapToDouble(s -> Double.parseDouble((s.getShipmentReviewQuantity() == null ? 0 : s.getShipmentReviewQuantity()).toString())).sum();
            var sumShipmentReviewAmount = data.stream().mapToDouble(s -> Double.parseDouble((s.getShipmentReviewAmount() == null ? 0 : s.getShipmentReviewAmount()).toString())).sum();
            var tcprice = data.stream().mapToDouble(s -> Double.parseDouble((s.getCommissionPrice() == null ? 0 : s.getCommissionPrice()).toString())).sum();
            var tcmoney = data.stream().mapToDouble(s -> Double.parseDouble((s.getCommissionMoney() == null ? 0 : s.getCommissionMoney()).toString())).sum();
            map.put("sumQuantity", sumQuantity);
            map.put("sumVolume", sumVolume);
            map.put("sumShipmentReviewVolume", sumShipmentReviewVolume);
            map.put("sumShipmentReviewQuantity", sumShipmentReviewQuantity);
            map.put("sumShipmentReviewAmount", sumShipmentReviewAmount);
            map.put("tcprice", tcprice);
            map.put("tcmoney", tcmoney);
            svSVC.updateUserMenuView(query);
            return success("ok", map);
        } catch (Exception ee) {
            return error(ee);
        }
    }

    @ApiOperation(value = "查询产品发货明细", notes = "根据发货单编号获取发货明细")
    @GetMapping("order/detail/{orderSN}")
    public WebResult getOrderDetail(@PathVariable String orderSN) {
        try {
            var detail = shipService.getDetailByOrderSN(orderSN);
            return success("ok", detail);
        } catch (Exception ee) {
            return error(ee);
        }
    }

    @ApiOperation(value = "查询产品发货单", notes = "分页查询产品发货单")
    @RequestMapping(value = "freight/{rowNum}/{page}", method = RequestMethod.POST)
    public WebResult queryFreightPage(@RequestBody PageQuery query,
                                      @ApiParam(value = "页码") @PathVariable int page,
                                      @ApiParam(value = "每页条数") @PathVariable int rowNum) {
        try {
            var result = shipService.queryFreightPage(query, rowNum, page);
            svSVC.updateUserMenuView(query);
            return success("ok", result);
        } catch (Exception ee) {
            return error(ee);
        }
    }

    @ApiOperation(value = "查询产品发货单", notes = "分页查询产品发货单")
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public WebResult saveOrder(@ApiParam(value = "提交信息") @RequestBody SubmitModel model) {
        try {
            var result = shipService.saveOrder(model);
            return success("ok", result);
        } catch (Exception ee) {
            return error(ee);
        }
    }

    @ApiOperation(value = "保存审核信息", notes = "保存发货单审核信息")
    @RequestMapping(path = "review", method = RequestMethod.POST)
    public WebResult saveReview(@ApiParam(value = "提交信息") @RequestBody SubmitModel submitModel) {
        Integer result = shipService.saveReviewOrders(submitModel);
        if (result > 0) {
            return success("审核完成");
        } else {
            return fail("审核失败");
        }
    }

    @ApiOperation(value = "保存批量审核信息", notes = "保存发货单批量审核信息")
    @RequestMapping(path = "batch_review", method = RequestMethod.POST)
    public WebResult saveBatchReview(@ApiParam(value = "提交信息") @RequestBody SubmitModel submitModel) {
        Integer result = shipService.saveBatchReviewOrders(submitModel);
        if (result > 0) {
            return success("审核完成");
        } else {
            return fail("审核失败");
        }
    }

    @ApiOperation(value = "取消审核信息", notes = "保存发货单审核信息")
    @RequestMapping(path = "cancelBatchReview/{sn}", method = RequestMethod.PUT)
    public WebResult cancelBatchReview(@PathVariable String sn) {
        Integer result = shipService.cancelBatchReview(sn.split(","));
        if (result > 0) {
            return success("取消成功");
        } else {
            return fail("取消失败");
        }
    }

    @ApiOperation(value = "取消审核信息", notes = "保存发货单审核信息")
    @RequestMapping(path = "cancelReview/{sn}", method = RequestMethod.PUT)
    public WebResult cancelReview(@PathVariable String sn) {
        Integer result = shipService.cancelReview(sn.split(","));
        if (result > 0) {
            return success("取消成功");
        } else {
            return fail("取消失败");
        }
    }

    @ApiOperation(value = "保存运费审核信息", notes = "保存发货单运费审核信息")
    @RequestMapping(path = "freightReview", method = RequestMethod.POST)
    public WebResult saveFreightReview(@ApiParam(value = "提交信息") @RequestBody SubmitModel submitModel) {
        Integer result = shipService.saveFreightReviewOrders(submitModel);
        if (result > 0) {
            return success("审核完成");
        } else {
            return fail("审核失败");
        }
    }

    @ApiOperation(value = "保存签收信息", notes = "保存发货单签收信息")
    @RequestMapping(path = "sign", method = RequestMethod.POST)
    public WebResult saveSignInfo(@ApiParam(value = "提交信息") @RequestBody SubmitModel submitModel) {
        try {
            Integer result = shipService.saveSignInfo(submitModel);
            if (result > 0) {
                return success("保存成功");
            } else {
                return fail("保存失败");
            }
        } catch (Exception ee) {
            return error(ee);
        }
    }

    @ApiOperation(value = "作废发货单", notes = "作废发货单")
    @RequestMapping(path = "invalid/{sn}", method = RequestMethod.POST)
    public WebResult invalidOrder(@PathVariable String sn, @RequestParam String cause) {
        try {
            Integer result = shipService.invalidOrder(sn, cause);
            if (result > 0) {
                return success("作废成功");
            } else {
                return fail("作废失败");
            }
        } catch (Exception ee) {
            return error(ee);
        }
    }
    @ApiOperation(value = "恢复发货单", notes = "作废发货单")
    @RequestMapping(path = "restore/{sn}", method = RequestMethod.GET)
    public WebResult restoreOrder(@PathVariable String sn) {
        try {
            Integer result = shipService.restoreOrder(sn);
            if (result > 0) {
                return success("作废成功");
            } else {
                return fail("作废失败");
            }
        } catch (Exception ee) {
            return error(ee);
        }
    }

    @ApiOperation(value = "用友系统对接发货明细导出", notes = "用友系统对接发货明细导出")
    @PostMapping(path = "/orderExport")
    public void exportOrders(@RequestBody PageQuery query, HttpServletResponse response) {
        try {
            var orderList = shipService.queryExportOrderList(query);
            List<ExcelMap> maps = new ArrayList<>();
            maps.add(new ExcelMap(0, "outTime", ""));
            maps.add(new ExcelMap(1, "sn", ""));
            maps.add(new ExcelMap(2, "customerBN", ""));
            maps.add(new ExcelMap(3, "customerName", ""));
            maps.add(new ExcelMap(4, null, "15"));
            maps.add(new ExcelMap(6, null, "专用发票"));
            maps.add(new ExcelMap(8, null, "纸票"));
            maps.add(new ExcelMap(9, "customerBN", ""));
            maps.add(new ExcelMap(10, "customerName", ""));
            maps.add(new ExcelMap(25, null, "201"));
            maps.add(new ExcelMap(26, null, "销售出库"));
            maps.add(new ExcelMap(31, "remark", ""));
            maps.add(new ExcelMap(32, null, "04"));
            maps.add(new ExcelMap(38, "productBN", ""));
            maps.add(new ExcelMap(39, "productName", ""));
            maps.add(new ExcelMap(41, "shipmentReviewQuantity", 0.0D));
            maps.add(new ExcelMap(42, "shipmentReviewVolume", 0.0D));
            maps.add(new ExcelMap(50, "price", 0.0D));
            maps.add(new ExcelMap(52, "amount", 0.0D));
            var util = new ExcelMapUtil("brickShipOrderTemp");
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Expose-Headers", "File-Name");
            response.setContentType("application/force-download;charset=UTF-8");

            //String cateName = HsApp.getProductCateName(Tl.getString(query.getQuery().get("productCateSN")));
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("加气块产品发货单.xlsx", StandardCharsets.UTF_8));
            response.setHeader("File-Name", URLEncoder.encode("加气块产品发货单.xlsx", StandardCharsets.UTF_8));
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            var orderPath = tmpPath;
            var buffer = util.exportByTemplate(orderPath, 2, orderList, maps);//第三行
            response.addHeader("Content-Length", "" + buffer.length);
            outputStream.write(buffer);
            outputStream.flush();
        } catch (Exception ee) {
            log.error("导出错误", ee);
        }
    }

    @Value("${template.brickShipOrder.Excel}")
    private String tmpPath;


    @Autowired
    public void setShipService(IBrickShipService shipService) {
        this.shipService = shipService;
    }

    @Autowired
    public void setSvSVC(ISearchViewService svSVC) {
        this.svSVC = svSVC;
    }

    private IBrickShipService shipService;
    private ISearchViewService svSVC;


    @ApiOperation(value = "车辆托盘使用汇总", notes = "分页查询车辆托盘使用汇总")
    @PostMapping("trayStatistics/{rowNum}/{page}")
    public WebResult trayStatistics(@RequestBody PageQuery query,
                                    @ApiParam(value = "页码") @PathVariable int page,
                                    @ApiParam(value = "每页条数") @PathVariable int rowNum) {
        try {
            return success("ok", shipService.trayStatistics(query, page, rowNum));
        } catch (Exception ee) {
            return error(ee);
        }
    }

    @ApiOperation(value = "根据单据编号更该打印次数", notes = "根据单据编号更该打印次数")
    @GetMapping("updatePrintCount/{sn}")
    public WebResult updatePrintCount(@PathVariable String sn) {
        try {
            var result = shipService.updatePrinCount(sn);
            if(result>0){
                return success("更改成功");
            }else{
                return fail("更改失败");
            }
        }catch (Exception ee){
            return  error(ee.toString());
        }
    }
    @ApiOperation(value = "根据单据编号更该产品净重", notes = "根据单据编号更该产品净重")
    @GetMapping("updateWeight/{sn}/{weight}")
    public WebResult updateWeight(@PathVariable String sn,@PathVariable  BigDecimal weight){
        var result = shipService.updateWeight(sn,weight);
        if(result>0){
            return success("操作成功");
        }else if(result ==0 ){
            return fail("未找到数据");
        }else{
            return error("系统错误");
        }
    }
}
